package cn.le.server;

import cn.le.handler.InactiveHandler;
import cn.le.handler.banks.LoginHandler;
import cn.le.handler.ReadFilterHandler;
import cn.le.handler.banks.SendMsgHandler;
import cn.le.messagePack.*;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;


public class NettyServer {

    public static void start(LoginHandler loginHandler, SendMsgHandler sendMsgHandler){
        new MessagePackDecoder();
        //连接线程池
        EventLoopGroup boosGroup = new NioEventLoopGroup(10);
        //工作线程池
        EventLoopGroup workGroup = new NioEventLoopGroup(20);
        try {
            //创建nio服务
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boosGroup, workGroup)
                    .channel(NioServerSocketChannel.class);

            //定义处理器
            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    //拆包解码器 接收消息使用NettyMsg类型
                    socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(65535,0,
                            4,0,4));
                    //把拆包后的byte数据转成对象
                    socketChannel.pipeline().addLast(new MessagePackDecoder());
                    //定长编码器,按照第一个位置保持数据长度 ,回复消息采用Response类型
                    socketChannel.pipeline().addLast(new LengthFieldPrepender(4));
                    //对象序列化
                    socketChannel.pipeline().addLast(new MessagePackEncoder());
                    //心跳检测
                    socketChannel.pipeline().addLast(new IdleStateHandler(125,185,300));
                    //链接断开处理
                    socketChannel.pipeline().addLast(new InactiveHandler());
                    //消息处理
                    socketChannel.pipeline().addLast(new ReadFilterHandler());
                }
            });
            bootstrap.option(ChannelOption.SO_BACKLOG, 128);
            bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture future = bootstrap.bind(8081).sync();
            future.channel().closeFuture().sync();//等待socket被关闭
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            workGroup.shutdownGracefully();
            boosGroup.shutdownGracefully();
        }
    }

}
